package com.zk.curator.lock;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * <h3>partitionjob</h3>
 * <p>分布式锁核心1</p>
 *
 * 分布式锁的核心接口 ： 尝试获取锁
 * public void acquire() throws Exception;
释放锁
 public void release() throws Exception;

 * @author : hduong
 * @version : 1.0
 * @date : 2019-12-24 09:44
 **/
public class DistributedLock1 {

    //定义每次会话 -- session -- 一次连接后的沟通的的超时时间
    static final int SESSION_TIME = 5000; //ms 毫秒

    static int count = 10;

    public static void geneaNo() {
        try {
            System.out.println("count : " + count--);
        } finally {

        }
    }

    public static void main(String[] args) throws InterruptedException {
        //1: 重试策略 ： 网络原因 必须有重试策略 : 指数级方式 重试
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        //2: 通过工厂创建连接 ： 工厂模式
        CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
                .connectString("192.168.80.3:2181")
                .sessionTimeoutMs(SESSION_TIME)
                .retryPolicy(retryPolicy)
//                .namespace("/super")
                .build();
        //3: 开启连接
        curatorFramework.start();
        //4: 分布式锁
        final InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/super");
        final CountDownLatch countDownLatch = new CountDownLatch(1);

        for (int i = 0; i < 10; i ++ ) {
            new Thread(() -> {
                try {
                    //阻塞当前线程： 这里的阻塞需要在外面进行 计数器减少才能唤醒线程抢占分布式环境中的锁
                    countDownLatch.await();
                    //加锁 : 分布式锁中的加锁
                    lock.acquire();
                    System.out.println(Thread.currentThread().getName() + "开始执行业务逻辑...");
                    TimeUnit.SECONDS.sleep(2);//业务处理中
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        System.out.println(Thread.currentThread().getName() + "执行结束.\n");
                        //释放分布式环境中的锁
                        lock.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, "线程-" + i).start();
        }
        TimeUnit.SECONDS.sleep(1);
        //唤醒上面阻塞的线程
        countDownLatch.countDown();
    }
}
